﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Tasks;
using System.Reflection;
using System.Windows.Threading;
using Chrysalis.Internal;

namespace Chrysalis.Services
{
    public class ChooserExecutionService : IChooserExecutionService, IHasSessionState
    {
        // *** Fields ***

        private IChooserExecutionContext currentContext;

        // *** Methods ***

        public void ExecuteChooser<T>(ChooserBase<T> chooser, Action<T> callback) where T : TaskEventArgs
        {
            // Check that the callback is a method of the current view model (otherwise we cannot find the method after tombstoning)

            if (callback.Target != ChrysalisService.Current.CurrentViewModel)
                throw new InvalidOperationException("To use the ChooserExecutionService, property 'callback' must be a method on the current view model");

            // Create a ChooserExecutionContext to store the information required 

            ChooserExecutionContext<T> context = new ChooserExecutionContext<T>()
                {
                    ChooserTypeName = chooser.GetType().AssemblyQualifiedName,
                    CallbackMethod = callback.Method.Name
                };

            currentContext = context;

            // Attach to the chooser.Completed event - This may be called if the phone decides not to tombstone
            // NB: This needs to be the same signature as that reattached upon activation from tombstoning

            chooser.Completed += new EventHandler<T>(context.Chooser_Completed);

            // Show the chooser

            chooser.Show();
        }

        // *** IHasSessionState Methods ***

        void IHasSessionState.Initialize(object state)
        {
            // If a chooser execution context has been stored from a previous instance, then reattach to the event handler

            IChooserExecutionContext context = state as IChooserExecutionContext;

            if (context != null)
                context.Attach();
        }

        object IHasSessionState.SaveState()
        {
            // If the current context is still active (i.e. this isn't a stale context from a previous chooser call) then persist it

            if (currentContext != null && currentContext.IsActive)
                return currentContext;
            else
                return null;
        }
    }
}
